﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tasker.Composition;
using Tasker.Infrastructure;
using Tasker.Infrastructure.Entities;
using Tasker.Infrastructure.Repositories.Base;
using Tasker.Infrastructure.Services;
using Tasker.WebUI.Models.Task;

namespace Tasker.WebUI.Controllers
{
    public class TaskController : TaskerControllerBase
    {
        //
        // GET: /Task/

        private ITaskService _tasks = Resolver.Resolve<ITaskService>();
        private IAccountService _account = Resolver.Resolve<IAccountService>();

        public ActionResult Index(int id)
        {
            ITask task = _tasks.SelectTask(id);
            TaskShowModel model = new TaskShowModel();
            model.Id = task.Id;
            model.Name = task.Name;
            model.Description = task.Description;
            model.CreatedDate = task.CreatedDate;
            model.StartDate = task.StartDate;
            model.FinishDate = task.FinishDate;
            if(task.ParentId != null)
            {
                model.ParentId = (int)task.ParentId;
                model.ParentTaskName = _tasks.SelectTask(model.ParentId).Name;
            }

            IUser user = _account.SelectUser(task.AuthorId);
            model.AuthorId = user.Id;
            model.AuthorNick = user.Login;
            model.AuthorFullName = UserFullName(user);
            model.AuthorPosition = user.Position;

            IEnumerable<IUser> users = _tasks.GetTaskWorkers(id);

            model.TaskWorkers = from us in users
                                select new TaskUserModel()
                                           {
                                               Id = us.Id,
                                               FullName = FullName(us.FirstName, us.LastName, us.Login),
                                               Position = us.Position
                                           };

            IStatus status = _tasks.GetTaskStatus(task.StatusId);
            model.StatusId = status.Id;
            model.Status = status.Name;

            return View("Show", model);
        }

        [HttpPost]
        public ActionResult Complete(int id)
        {
            var context = Resolver.Resolve<IContextManager>();
            context.Begin();

            ITask task = _tasks.SelectTask(id);
            task.StatusId = 4;
            _tasks.UpdateTask(task);
            _tasks.CompleteAllSubTasks(task.Id);

            context.Commit();

            return RedirectToAction("Index", new {id=id});
        }

        [HttpPost]
        public ActionResult Stop(int id)
        {
            var context = Resolver.Resolve<IContextManager>();
            context.Begin();

            ITask task = _tasks.SelectTask(id);
            task.StatusId = 3;
            _tasks.UpdateTask(task);

            context.Commit();

            return RedirectToAction("Index", new { id = id });
        }

        [HttpPost]
        public ActionResult InProccess(int id)
        {
            var context = Resolver.Resolve<IContextManager>();
            context.Begin();

            ITask task = _tasks.SelectTask(id);
            task.StatusId = 2;
            _tasks.UpdateTask(task);

            context.Commit();

            return RedirectToAction("Index", new { id = id });
        }

        public ActionResult Create()
        {
            
            TaskCreateModel model = new TaskCreateModel();

            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();
            model.TaskWorkers = new TaskUserModel[0] { };

            model.StartDate = DateTime.Today;
            model.FinishDate = DateTime.Today;

            return View(model);
        }

        [HttpPost]
        public ActionResult CreateSubTask(int parentTaskId)
        {
            TaskCreateModel model = new TaskCreateModel();

            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();
            model.TaskWorkers = new TaskUserModel[0] { };
            model.TaskId = parentTaskId;

            model.StartDate = DateTime.Today;
            model.FinishDate = DateTime.Today;

            return View("Create", model);
        }

        [HttpPost]
        public ActionResult CreateTaskEmployee(int employeeId)
        {
            TaskCreateModel model = new TaskCreateModel();

            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();
            model.TaskWorkers = new TaskUserModel[0] { };
            model.EmployeeId = employeeId;

            model.StartDate = DateTime.Today;
            model.FinishDate = DateTime.Today;

            return View("Create", model);
        }

        [HttpPost]
        public ActionResult Create(TaskCreateModel model, string returnUrl, IEnumerable<string> task_workers, string parentTaskId)
        {
            if (task_workers == null)
            {
                ModelState.AddModelError("", "Добавте хотя бы одного исполнителя");
            }
            else if(ModelState.IsValid)
            {
                var context = Resolver.Resolve<IContextManager>();
                context.Begin();

                ITask task = _tasks.GetBlankEntity();
                task.Name = model.Name;
                task.Description = model.Description;
                task.CreatedDate = DateTime.Now;
                task.StartDate = model.StartDate;
                task.FinishDate = model.FinishDate;
                task.AuthorId = CurrentUserId;
                if (parentTaskId != null)
                {
                    task.ParentId = Int32.Parse(parentTaskId);
                }
                
                task = _tasks.AddTask(task);
                context.Commit();

                context.Begin();
                

                foreach (var taskWorker in task_workers)
                {
                    _tasks.CreateTaskWorker(task.Id, Int32.Parse(taskWorker));
                }

                context.Commit();


                if (!string.IsNullOrEmpty(returnUrl))
                    return Redirect(returnUrl);
                else
                    return RedirectToAction("Index", "Task", new {id=task.Id});
            }
            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();
            model.TaskWorkers = new TaskUserModel[0]{};
            return View(model);
        }

        public ActionResult Edit(int id)
        {
            ITask task = _tasks.SelectTask(id);

            if (task == null)
            {
                return RedirectToAction("Index", "Home");
            }

            IUser user = _account.SelectUser(task.AuthorId);
            if(user.Login != CurrentUserLogin)
            {
                return RedirectToAction("Index", "Home");
            }

            TaskEditModel model = new TaskEditModel();
            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();

            IEnumerable<IUser> users = _tasks.GetTaskWorkers(id);

            model.TaskWorkers = from us in users
                                select new TaskUserModel()
                                {
                                    Id = us.Id,
                                    FullName = FullName(us.FirstName, us.LastName, us.Login),
                                    Position = us.Position
                                };

            model.Name = task.Name;
            model.Description = task.Description;
            model.CreatedDate = task.CreatedDate;
            model.StartDate = task.StartDate;
            model.FinishDate = task.FinishDate;

            return View(model);
        }

        [HttpPost]
        public ActionResult Edit(TaskEditModel model, string returnUrl, int id, IEnumerable<string> task_workers)
        {
            if (task_workers == null)
            {
                ModelState.AddModelError("", "Добавте хотя бы одного исполнителя");
            }
            else if (ModelState.IsValid)
            {
                var context = Resolver.Resolve<IContextManager>();
                context.Begin();

                ITask task = _tasks.SelectTask(id);
                task.Name = model.Name;
                task.Description = model.Description;
                task.CreatedDate = DateTime.Now;
                task.StartDate = model.StartDate;
                task.FinishDate = model.FinishDate;

                _tasks.UpdateTask(task);

                _tasks.DeleteAllTaskWorkers(task.Id);

                foreach (var taskWorker in task_workers)
                {
                    _tasks.CreateTaskWorker(task.Id, Int32.Parse(taskWorker));
                }

                context.Commit();

                if (!string.IsNullOrEmpty(returnUrl))
                    return Redirect(returnUrl);
                else
                    return RedirectToAction("Index", "Task", new { id = task.Id });
            }
            model.Tasks = GetAllTasks();
            model.Users = GetAllUsers();

            IEnumerable<IUser> users = _tasks.GetTaskWorkers(id);

            model.TaskWorkers = from us in users
                                select new TaskUserModel()
                                {
                                    Id = us.Id,
                                    FullName = FullName(us.FirstName, us.LastName, us.Login),
                                    Position = us.Position
                                };
            return View(model);
        }

        [HttpPost]
        public ActionResult Delete(int id)
        {
            var context = Resolver.Resolve<IContextManager>();
            context.Begin();

            _tasks.DeleteTask(id);

            context.Commit();
            return RedirectToAction("Index", "Home");
        }


        private IEnumerable<Tuple<int, string>> GetAllTasks()
        {
            IEnumerable<ITask> tasks = _tasks.SelectAll();
            IEnumerable<Tuple<int, string>> res = from task in tasks
                          select new Tuple<int, string>(task.Id, task.Name);
            return res;
        }

        private IEnumerable<TaskUserModel> GetAllUsers()
        {
            IEnumerable<IUser> users = _account.SelectAllUsers();
            IEnumerable<TaskUserModel> res = from user in users
                                                  select new TaskUserModel()
                                                             {
                                                                 Id = user.Id,
                                                                 FullName = UserFullName(user),
                                                                 Position = user.Position
                                                             };
            return res;
        }

        

    }
}
